# ============================================================
# * Copyright © hk. 2022-2025. All rights reserved.
# * File name: CMakeLists.txt
# * Author   : 苏木
# * Date     : 2025-05-22
# * Version  : 
# * Description: cmake version 3.16.3
# ============================================================
## https://cmake.com.cn/cmake/help/latest/guide/tutorial/index.html
## https://cmake.org/cmake/help/latest/

# 指定 CMake 的最低版本要求
# --------------------------------------------------
cmake_minimum_required(VERSION 3.10)


# 设置项目名称和使用的编程语言
# --------------------------------------------------
project(SPROJECT C)


# 指定可执行程序和源文件
# --------------------------------------------------
add_executable(app_demo.out main.c)


# message([<mode>] "message text" ...)
# --------------------------------------------------
message(STATUS "This is a message print! mode=STATUS")


# 1. 普通变量：CMake 变量的值总是以字符串类型，尽管一些命令可能会将字符串解释为其他类型的值，例如布尔值、数值、路径。
# --------------------------------------------------
# 注意：${}来引用变量，这是 cmake 的变量应用方式，但是，有一些例外，比如在 IF 控制语句，变量是直接使用变量名引用，而不需要${}。
message(STATUS "==> 普通变量")
# 1.1 字符串变量
set(MY_STRING "Hello World")
message(STATUS "String variable: ${MY_STRING}")

# 1.2 列表变量
set(MY_LIST 1 2 3 4 5)
message(STATUS "List variable: ${MY_LIST}")

# 1.3 布尔变量
set(MY_BOOL ON) # TRUE或者ON 
IF(MY_BOOL) # 这里先用一下判断语句，后面再学习
	message(STATUS "Boolean variable is TRUE")
ELSE()
	message(STATUS "Boolean variable is FALSE")
ENDIF()
message("")

# 2. 环境变量：环境变量在 CMake 执行过程中具有全局范围，并且它们永远不会被缓存。
# --------------------------------------------------
# 环境变量的初始化是调用进程时的初始化。我们可以使用 set() 命令设置环境变量，使用 unset() 命令取消环境变量。
# 这些命令只影响正在运行的 CMake 进程，而不影响整个系统环境。
# 更改环境变量的值，不会写入调用进程，也不会被后续的构建或检测进程看到。
message(STATUS "==> 环境变量")
set(ENV{PATH} "/tmp;$ENV{PATH}")
message(STATUS "PATH   : $ENV{PATH}")
message(STATUS "CC     : $ENV{CC}")
message(STATUS "CFLAGS : $ENV{CFLAGS}")
message("")

# 3. 缓存变量：CMake 存储一组单独的 "缓存变量" 或 "缓存条目"，因为在项目构建树中的多次运行时，我们需要变量的值保持不变。
# --------------------------------------------------
# set(<variable> <value> ... CACHE <type> <docstring> [FORCE])
# CMakeCache.txt 文件用于存储缓存条目，第一次构建时会生成该文件，之后的构建并不会创建该文件。在引用缓存条目时，会去查找该文件，并返回值。
# FORCE          在使用 set() 命令时，默认情况下，如果缓存条目在 CMakeCache.txt 文件不存在，会创建缓存条目，并写入到 CMakeCache.txt 
#                文件中。如果缓存条目在 CMakeCache.txt 文件存在，忽略 set() 命令，不会覆盖现有的缓存条目。但是我们想强制覆盖现有的缓存条目，
#                我们可以 FORCE 选项。
message(STATUS "==> 缓存变量")
set(MY_CACHE_VAR "cache str" CACHE STRING "cached variable")
message(STATUS "MY_CACHE_VAR : ${MY_CACHE_VAR}")
message("")

#  4. 预定义变量
# --------------------------------------------------
message(STATUS "==> 环境变量")
message(STATUS "CMAKE_SOURCE_DIR         : ${CMAKE_SOURCE_DIR}")   # 项目根目录的路径
message(STATUS "CMAKE_BINARY_DIR         : ${CMAKE_BINARY_DIR}")   # 编译目录的路径
message(STATUS "CMAKE_CURRENT_BINARY_DIR : ${CMAKE_CURRENT_BINARY_DIR}") # 当前处理 CMakeLists.txt 文件的二进制输出目录
message(STATUS "CMAKE_CURRENT_SOURCE_DIR : ${CMAKE_CURRENT_SOURCE_DIR}") # 当前处理 CMakeLists.txt 文件的源码目录
message(STATUS "CMAKE_PROJECT_NAME       : ${CMAKE_PROJECT_NAME}") # 当前项目名称
message(STATUS "CMAKE_VERSION            : ${CMAKE_VERSION}")      # 当前 CMake 版本
message(STATUS "WIN32 : ${WIN32}")   # WIN32 在 Windows 环境中为 TRUE
message(STATUS "UNIX  : ${UNIX}")    # UNIX 在 UNIX 环境中为 TRUE
message(STATUS "APPLE : ${APPLE}")   # APPLE 在苹果 macOS 环境下为 TRUE
message("")

#  5. 变量计算
# --------------------------------------------------
# CMake提供了math()命令来执行基本的数学计算：math(EXPR outVar mathExpr)
# 第一个参数必须使用关键字EXPR，而mathExpr定义要计算的表达式，结果将存储在outVar中。
# 表达式可以使用以下操作符中的任何一个，这些操作符在C代码中的含义相同：+ - * / % | & ^ ~ << >> * / %。
# 也支持括号，并且具有常规的数学意义。mathExpr中变量可以使用${myVar}进行定义后引用。
message(STATUS "==> 变量的运算")
set(x 3)
set(y 7)
math(EXPR z "(${x}+${y})/2")
message(STATUS "(${x}+${y})/2 = ${z}")
message("")